package cn.edu.gsau.info.service.impl;

import cn.edu.gsau.info.dao.MenuMapper;
import cn.edu.gsau.info.dao.UserDao;
import cn.edu.gsau.info.models.*;

import cn.edu.gsau.info.service.IUserService;
import cn.edu.gsau.info.util.JwtUtil;
import cn.edu.gsau.info.util.RedisCache;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;

@JsonSerialize
@Service
public class UserServiceImpl extends ServiceImpl<UserDao,User> implements IUserService {
    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    RedisCache redisCache;
    @Autowired
    MenuMapper menuMapper;
    @Autowired
    UserDao userDao;

    @Override
    public ResponseResult getMenuAndUser(LoginUser loginUser) {
        //从上下文中取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser1= (LoginUser) authentication.getPrincipal();

        //从数据库中取菜单信息
        List<Menu> menu = menuMapper.selectMenuByUserId(loginUser.getUser().getId());

        //通过map响应用户信息和菜单信息
        Map<String,Object> map = new HashMap<>();
        map.put("user",loginUser1);
        map.put("menu",menu);


        return new ResponseResult(200,"获取成功",map);
    }

    @Override
    public ResponseResult login(User user ) {

        //1：调用 AuthenticationManager 接口的 authenticate 方法进行用户认证
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user.getUserName(),user.getPassword());

        Authentication authenticate = authenticationManager.authenticate(authentication);

        //2：如果认证没有通过，抛出异常，给出提示
        if(Objects.isNull(authenticate)){
            throw  new RuntimeException("登录失败");
        }

        //3：如果认证通过，根据用户的 userid 生成 token
        LoginUser loginUser = (LoginUser)authenticate.getPrincipal();
        System.out.println(loginUser.getUsername()+loginUser.getNickName());
        String userid = loginUser.getUser().getId().toString();
        String jwt = JwtUtil.createJWT(userid);
        Map<String,Object> map = new HashMap<>();
        map.put("token",jwt);


        //4：将用户信息存入redis，userid作为key,有效期为12小时
        redisCache.setCacheObject("login:"+userid,loginUser,12, TimeUnit.HOURS);

        //5：向前端响应登录结果
        return new ResponseResult(200,"登录成功",map);
    }

    @Override
    public ResponseResult logout() {
        //1:从 SecurityContextHolder 上下文中获取 userid
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Long userid = loginUser.getUser().getId();


        //2:将用户从redis中删除
        redisCache.deleteObject("login:"+userid);

        //3:响应结果
        return new ResponseResult(200,"退出成功");
    }
    @Override
    @Transactional
    public ResponseResult insert(BigUser bigUser) {
        userDao.insert(bigUser.getUser());


        return new ResponseResult(200,"成功");
    }



}